/*
 * Web Crawler
 * Date: November 01, 2011
 * Group JEDi
 * Author(s): James Lovato, Efim Todorasco, Daniel Garrison
 */
package singlethread;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * Class that parses a web page looking for other links and keeps track
 * of how many links that have been found.
 * 
 * @author James Lovato, Efim Todorasco, Daniel Garrison
 * @version 10/20/11
 */
public class CrawlerParser {
	
	/**
	 * All the numbers of times each word is located within the 
	 * parsed document.
	 */
	private int[] my_word_counts;
	
	/**
	 * The words that are going to be searched for within each
	 * document.
	 */
	private String[] my_search_words;
	
	/**
	 * The total number of words within the document.
	 */
	private int my_num_of_words;
	
	/**
	 * The list of links found during the parsing. 
	 */	
	private List<String> my_links = new ArrayList<String>();
	
	/**
	 * @param the_search_words an array of words to search for.
	 */
	public CrawlerParser(String[] the_search_words) {
		my_search_words = the_search_words;
		my_word_counts = new int[the_search_words.length];
	}	
	
	/**
	 * Parses the web document locating all valid href tags.
	 * 
	 * @throws IOException
	 */
	public void parsePage(final Document the_page) throws IOException {
		if (!the_page.baseUri().endsWith("txt")) {
			Elements links = the_page.select("a[href]");		
			for (Element link : links) {								
				if (goodHrefCheck(link.toString()) && !badHrefCheck(link.toString())) {										
					if (link.attr("abs:href").toString().contains("#")) {
						my_links.add(link.attr("abs:href").substring(0, link.attr("abs:href").indexOf("#")));
					} else {
						my_links.add(link.attr("abs:href"));
					}			
				}
			}
		}
		countWords(the_page);
	}
	
	/**
	 * @param the_link The link to be checked.
	 * @return Is this a good link?
	 */
	private boolean goodHrefCheck(final String the_link) {
		boolean boo = false;
		if (the_link.contains("html")) {
			boo = true;
		} else if (the_link.contains("htm")) {
			boo = true;
		} else if (the_link.contains("txt")) {
			boo = true;
		} else if (the_link.contains("http")) {
			boo = true;
		}
		return boo;
	}
	
	/**
	 * @param the_link The link to be checked.
	 * @return Is this a bad link?
	 */
	private boolean badHrefCheck(final String the_link) {
		boolean boo = false;
		if (the_link.contains("google.com")) {
			boo = true;
		} else if (the_link.contains("youtube.com")) {
			boo = true;
		} else if (the_link.contains("twitter.com")) {
			boo = true;
		} else if (the_link.contains("facebook.com")) {
			boo = true;
		} else if (the_link.contains("http://validator.w3.org/")) {
			boo = true;
		} else if (the_link.contains("http://questioneverything.typepad.com/")) {
			boo = true;
		}
		return boo;
	}
	
	/**
	 * Prepares the document for data gathering.
	 * Counts the number of "hit" words on the page and tallies them in the word_counter.
	 * @param the_doc The document to be processed.
	 */
	public void countWords(Document the_document){
		String text;
		try {
			text = the_document.body().text();
		} catch (NullPointerException e) {
			text = "";
		}
	    String text1 = text.replaceAll("[^\\p{L}]", " ");
	    text1 = text1.toLowerCase();
	    String s[] = text1.split("\\s+");
	    my_num_of_words = s.length; // the total number of words within the doc
	    for (String st:s){
	    	for (int i = 0; i < my_search_words.length; i++) {
	            if (my_search_words[i].equals(st)) {
	            	my_word_counts[i]++;
	            }
	    	}
	    }
	}	
	
	/**
	 * @return What are the links?
	 */
	public List<String> getMyLinks() {
		return my_links;
	}
	
	/**
	 * @return What is the number of links found within the document?
	 */
	public int numberOfLinks() {
		return my_links.size();
	}
	
	/**
	 * @return What is the array with the number of hits on each word?
	 */
	public int[] wordCounts() {
		return my_word_counts;
	}
	
	/**
	 * @return What is the total number of words within the document?
	 */
	public int numberOfWords() {
		return my_num_of_words;
	}
}
